﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient;
using System.Data;
using System.Transactions;

namespace AtmTransaction
{
    class Withdraw
    {
        public const string CONECTION_STRING = "Server=.\\SQLEXPRESS;" +
                             " Database=ATM; Integrated Security=true";

        public static void AccountTransaction(SqlConnection DbCon,int acountNumber, decimal amount) 
        {
            using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required))
            {

                SqlCommand com = DbCon.CreateCommand();
                com.CommandText = "INSERT INTO AccountTransactions (CardNumber, TransactionDate, Ammount) "+
                    "VALUES (@acountNumber, @date, @amount)";
                com.Parameters.Add("@acountNumber", @acountNumber);
                com.Parameters.Add("@date", DateTime.Now);
                com.Parameters.Add("@amount", amount);
                com.ExecuteNonQuery();
                scope.Complete();
                
            }
        }

        public static void AtmWithdraw(int AccountNumber, string pin, decimal amount)
        {
            SqlConnection dbCon = new SqlConnection(CONECTION_STRING);
            if (pin.Length != 4)
            {
                throw new ArgumentOutOfRangeException("Invalid Pin size");
            }
            using(TransactionScope scope  = new TransactionScope())
            {
                dbCon.Open();
                using (dbCon)
                {
                    SqlCommand cmd = dbCon.CreateCommand();
                    try
                    {
                        cmd.CommandText = "SELECT CardNumber , CardPIN, CardCash " +
                            "FROM CardAccounts " +
                            "Where CardNumber = @AccountNumber AND CardPIN=@pin AND CardCash>=@amount ";
                        cmd.Parameters.Add("@AccountNumber", AccountNumber);
                        cmd.Parameters.Add("@pin", pin);
                        cmd.Parameters.Add("@amount", amount);
                        SqlDataReader reader = cmd.ExecuteReader();
                        using (reader)
                        {
                            if (reader.Read() == null)
                            {
                                throw new ArgumentOutOfRangeException("Invalid Account Number");
                            }
                            decimal accountSum = (decimal)reader["CardCash"];
                            accountSum -= amount;
                            cmd.Parameters.Add("@accountSum", accountSum);
                            cmd.CommandText = "UPDATE CardAccounts " +
                                "SET CardCash = @accountSum " +
                                "Where CardNumber = @AccountNumber";
                        }
                        cmd.ExecuteNonQuery();
                        AccountTransaction(dbCon,AccountNumber, amount);
                        scope.Complete();
                        Console.WriteLine("Transaction Successfull");

                    }
                    catch
                    {
                        Console.WriteLine("Transaction Fail");
                    }

                }

            }
        }

        public static void CheckWithdraws(int account, string pin)
        {
            SqlConnection DbCon = new SqlConnection();
            DbCon.Open();
            using (DbCon) 
            {
                SqlCommand cmd = DbCon.CreateCommand();
                cmd.CommandText = "SELECT a.* "+
                    "FROM AccountTransactions a "+
                    "JOIN CardAccounts c ON a.CardNumber = c.CardNumber "+
                    "WHRE a.CardNumber = @account AND c.CardPIN = @pin";
                cmd.Parameters.Add("@account", account);
                cmd.Parameters.Add("@account", pin);
                SqlDataReader reader = cmd.ExecuteReader();
                using (reader) 
                {
                    while (reader.Read()) 
                    {

                    }
                }
            }
        }

        static void Main(string[] args)
        {
            AtmWithdraw(321, "rewq", 200);
            AtmWithdraw(333, "1234", 200);
            AtmWithdraw(222, "xzaq", 200);
            CheckWithdraws(222, "xzaq");
        }
    }
}
